/*---------- fat32.c ----------*/
#include "vfs.h"

#define FAT32_EOC 0x0FFFFFF8  // End Of Cluster chain

typedef struct {
    uint16_t bytes_per_sector;
    uint8_t  sectors_per_cluster;
    uint16_t reserved_sectors;
    uint8_t  num_fats;
    uint32_t sectors_per_fat;
    uint32_t root_cluster;
} fat32_bpb_t;

typedef struct {
    uint32_t* fat_table;
    uint32_t  data_start;
    uint32_t  bytes_per_cluster;
} fat32_private_t;

// 获取FAT表项
static uint32_t get_fat_entry(fat32_private_t* priv, uint32_t cluster) {
    return priv->fat_table[cluster];
}

// 设置FAT表项
static void set_fat_entry(fat32_private_t* priv, uint32_t cluster, uint32_t value) {
    priv->fat_table[cluster] = value;
}

// 查找空闲簇
static uint32_t find_free_cluster(fat32_private_t* priv) {
    for (uint32_t i = 2; ; i++) { // 簇0和1保留
        if (get_fat_entry(priv, i) == 0) return i;
    }
    return 0; // 无空闲簇
}

// 计算簇对应的物理地址
static uint8_t* cluster_to_addr(vfs_filesystem_t* fs, fat32_private_t* priv, uint32_t cluster) {
    return fs->base_addr + priv->data_start + 
          (cluster - 2) * priv->bytes_per_cluster;
}

ssize_t fat32_write(vfs_inode_t* inode, const void* buf, size_t size, off_t offset) {
    vfs_filesystem_t* fs = (vfs_filesystem_t*)inode->i_private;
    fat32_private_t* priv = (fat32_private_t*)fs->fs_private;
    
    // 计算需要多少簇
    uint32_t needed_clusters = (size + priv->bytes_per_cluster - 1) / priv->bytes_per_cluster;
    
    // 分配簇链
    uint32_t prev_cluster = inode->i_cluster;
    for (int i = 0; i < needed_clusters; i++) {
        uint32_t new_cluster = find_free_cluster(priv);
        set_fat_entry(priv, prev_cluster, new_cluster);
        set_fat_entry(priv, new_cluster, FAT32_EOC);
        prev_cluster = new_cluster;
    }
    
    // 直接写入内存
    uint8_t* data_ptr = cluster_to_addr(fs, priv, inode->i_cluster) + offset;
    memcpy(data_ptr, buf, size);
    inode->i_size += size;
    
    // 更新目录项
    struct fat32_dir_entry* entry = (struct fat32_dir_entry*)inode->i_private;
    entry->file_size = inode->i_size;
    
    return size;
}

// FAT32操作实现
vfs_file_operations fat32_ops = {
    .write = fat32_write,
    // 其他操作...
};

int fat32_init(vfs_filesystem_t* fs) {
    fat32_bpb_t* bpb = (fat32_bpb_t*)fs->base_addr;
    
    fat32_private_t* priv = kmalloc(sizeof(fat32_private_t));
    priv->fat_table = (uint32_t*)(fs->base_addr + bpb->reserved_sectors * bpb->bytes_per_sector);
    priv->data_start = (bpb->reserved_sectors + bpb->num_fats * bpb->sectors_per_fat) * bpb->bytes_per_sector;
    priv->bytes_per_cluster = bpb->bytes_per_sector * bpb->sectors_per_cluster;
    
    fs->fs_private = priv;
    return 0;
}